<template>
  <div class="editor-com" style="width: 100%">
    <div style="border: 1px solid #ccc">
      <Toolbar
        style="border-bottom: 1px solid #ccc"
        :editor="editorRef"
        :defaultConfig="toolbarConfig"
        :mode="'default'"
        :key="selectedContent"
      />
      <Editor
        :key="selectedContent"
        style="width: 100%; overflow-y: hidden"
        :style="{ height: height + 'px' }"
        v-model="valueHtml"
        :defaultConfig="editorConfig"
        :mode="'simple'"
        @onCreated="handleCreated"
        @onChange="handleChange"
        @onBlur="handleBlur"
      />
    </div>
  </div>
</template>

<script setup>
import { ref, watch, shallowRef, onBeforeUnmount, onMounted, computed } from "vue";
import "@wangeditor/editor/dist/css/style.css"; // 引入 css
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { getFolder } from "@/utils/index";

// const props = defineProps(["modelValue"]);

const emit = defineEmits(["update:modelValue", "onBlur"]);
const props = defineProps({
  modelValue: {
    type: String,
    default: ""
  },
  toolbarKeys: {
    type: Array,
    default: () => {
      return ["uploadImage", "uploadVideo"];
    }
  },
  height: {
    type: Number,
    default: 220
  },
  isLimit: {
    type: Boolean,
    default: true
  },
  disabled: {
    type: Boolean,
    default: false
  }
});
// 内容 HTML
const valueHtml = ref(props.modelValue);

watch(
  () => props.disabled,
  val => {
    if (val) {
      editorRef.value.disable(); //禁用
    } else {
      editorRef.value.enable(); //取消禁用
    }
  },
  { immediate: false }
);

watch(
  () => props.modelValue,
  val => {
    if (val === null) {
      valueHtml.value = "";
    } else {
      valueHtml.value = JSON.parse(JSON.stringify(val));
    }
    // console.log("备注信息改变了222===", val);
  },
  { deep: true, immediate: false }
);

const handleChange = () => {
  // console.log(90909090, valueHtml.value);
  const totalLens = valueHtml.value.replace(/<[^>]+>/g, "").length;
  if (totalLens > 500 && props.isLimit === true) {
    ElMessage({
      message: "输入的字符不能超过500！",
      type: "error",
      grouping: true
    });
  } else {
    emit("update:modelValue", valueHtml.value);
  }
};

const handleBlur = () => {
  // console.log("失去了焦点");
  emit("onBlur", valueHtml.value);
};

//====================================富文本编辑器========================================================================================
// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef();
const toolbarConfig = {
  // excludeKeys: ["group-image", "group-video", "emotion", "insertLink"] //配置不显示的菜单-上传图片、上传视频 "group-image", "group-video",
  toolbarKeys: props.toolbarKeys //配置想要显示的菜单
};
const editorConfig = {
  placeholder: "请输入内容...",
  pointerEvents: "none",
  MENU_CONF: {
    uploadImage: {
      customUpload: async (file, insertFn) => {
        // console.log("触发图片上传");
        await handleAvatarChangeIcon(file);
        // console.log("上传图片的地址===", imgUrl.value);
        imgUrl.value && insertFn(imgUrl.value.split("?")[0]); // 最后插入图片 insertFn(url, alt, href)，alt：描述，href:链接，后面非必填
      }
    },
    uploadVideo: {
      customUpload: async (file, insertFn) => {
        // console.log("触发视频上传");
        await handleAvatarChangeIcon(file, "video");
        console.log("上传视频的地址===", videoUrl.value);
        videoUrl.value && insertFn(videoUrl.value.split("?")[0]); // 最后插入视频 insertFn(url, alt, href)，alt：描述，href:链接，后面非必填
      }
    }
  }
};
// const currentObj = ref({}); //当前点击的对象，用于富文本编辑器值的赋值
const imgUrl = ref(""); //编辑器每选择一次图片，上传后的地址
const videoUrl = ref(""); //编辑器每选择一次视频，上传后的地址

//为富文本编辑器添加key值，解决编辑成功后又重新打开时报错的问题
const selectedContent = computed(() => {
  return String(new Date().getTime());
});

const handleCreated = editor => {
  editorRef.value = editor; // 记录 editor 实例，重要！
  // console.log(909090, editor.getAllMenuKeys());
};
// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
  const editor = editorRef.value;
  if (editor == null) return;
  editor.destroy();
});

//====================================文件上传========================================================================================

import useMultipartOssStore from "@/store/modules/multipartOssStore.js";
import { ElMessage } from "element-plus";
const ossStore = useMultipartOssStore();

const handleAvatarChangeIcon = async (file, type = "img") => {
  //选中文件触发的change事件
  // console.log(file);

  if (type === "video") {
    const flag = await fileType(type, [file]);

    if (!flag) {
      ElMessage({
        message: "只能上传视频文件，并且视频时长不超过45秒，大小不超过100M",
        type: "error",
        offset: 60
      });
      videoUrl.value = ""; //视频校验失败，清空视频地址
      return;
    }
  }

  await customUpload({ file }, type);
};
/**
 * 校验文件类型
 */
const fileType = async (type, fileList) => {
  let flag = true;
  if (type === "img") {
    for (let item of fileList) {
      if (!((item.type === "image/jpeg" || item.type === "image/png") && item.size <= 1024 * 1024 * 5)) {
        flag = false;
      }
      if (!(item.type === "image/jpeg" || item.type === "image/png")) {
        flag = false;
      }
    }
  } else if (type === "video") {
    for (let item of fileList) {
      console.log("视频的大小===", item);
      if (!(item.type === "video/mp4" && item.size <= 1024 * 1024 * 100)) {
        flag = false;
      }
      if (item.type === "video/mp4") {
        await getTimes(item);
        // console.log("视频的时长===", item.raw.size <= 1024 * 1024 * 100, videoTime.value);
        if (!(videoTime.value <= 45)) {
          flag = false;
        }
      }
    }
  }
  return flag;
};
/**
 * 获取视频时间长度
 */
const videoTime = ref(0);
const getTimes = async file => {
  let content = file;
  //获取录音时长
  let url = URL.createObjectURL(content);
  //经测试，发现audio也可获取视频的时长
  let audioElement = new Audio(url);
  console.log(2222);
  await new Promise((resolve, reject) => {
    audioElement.addEventListener("loadedmetadata", _event => {
      //保存获取时间长度
      videoTime.value = parseInt(audioElement.duration);
      resolve("时长获取成功");
    });
  });
};
/**
 * 上传
 */
const getFileName = name => {
  const arr = name.split(".");
  const _arr = JSON.parse(JSON.stringify(arr));
  let _name = "";
  let _suffix = "";
  if (arr.length > 2) {
    _arr.splice(_arr.length - 1, 1);
    _name = _arr.join(".");
    _suffix = arr[arr.length - 1];
  } else {
    _name = arr[0];
    _suffix = arr[1];
  }
  const folder = getFolder();
  return folder + _name + new Date().getTime() + "." + _suffix;
};
const customUpload = async (option, type) => {
  const objName = getFileName(option.file.name);
  await ossStore
    .submit(objName, option.file)
    .then(async res => {
      await ossStore.setACL(objName, fileReadRole.publicRead);
      res.fileUrl = await ossStore.signatureUrl(objName);
      console.log("文件上传成功，地址为===", res.fileUrl);
      if (type === "img") {
        imgUrl.value = res.fileUrl.split("?")[0];
      } else {
        videoUrl.value = res.fileUrl.split("?")[0];
      }
    })
    .catch(err => {
      alert(JSON.stringify(err));
    });
};
const fileReadRole = {
  defaultRole: "",
  privateRole: "private",
  publicRead: "public-read",
  publicReadWrite: "public-read-write"
};
</script>

<style lang="scss" scoped>
:deep(.w-e-textarea-video-container) {
  video {
    width: 100% !important;
  }
}
:deep(.w-e-text-container) {
  P {
    width: 100% !important;
  }
}
:deep(.w-e-bar-item) {
  height: 20px !important;
  button {
    height: 20px;
  }
}
</style>
